<template>
  <el-row class="p-5 pt-0">

    <el-col :span="3">

      <el-row>

        <el-col>
          <el-input v-model="deptSearch" :disabled="loading" :size="store.layoutSize" clearable @input="searchDept"
                    placeholder="请输入部门名称">
            <template #prefix>
              <el-icon>
                <Search/>
              </el-icon>
            </template>
          </el-input>
        </el-col>

        <el-col class="mt-3">
          <el-tree :filter-node-method="filterNode" ref="treeRef" :expand-on-click-node="false" :data="tableData.data"
                   :default-expand-all="true" :props="{label:'deptName'}" node-key="deptId" @node-click="deptClick"/>
        </el-col>

      </el-row>

    </el-col>

    <el-col :span="21" @keyup.enter="getUserData">
      <el-row class="ml-5">

        <el-col v-if="showSearch">
          <el-form ref="searchForm" :inline="true" :model="search" class="demo-form-inline">
            <el-form-item label="用户名称" class="font-black">
              <el-input v-model="search.userName" :disabled="loading" :size="store.layoutSize" clearable
                        style="width: 130px"
                        placeholder="请输入用户名称"/>
            </el-form-item>
            <el-form-item label="手机号码" class="font-black">
              <el-input v-model="search.phonenumber" :disabled="loading" :size="store.layoutSize" clearable
                        style="width: 130px"
                        placeholder="请输入手机号码"/>
            </el-form-item>
            <el-form-item label="状态" class="font-black" style="width: 120px">
              <el-select v-model="search.status" :disabled="loading" :size="store.layoutSize" clearable
                         style="width: 150px"
                         placeholder="状态" @change="getUserData">
                <el-option v-for="item in statusData.data" :label="item.dictLabel" :value="item.dictValue"/>
              </el-select>
            </el-form-item>
            <el-form-item label="创建时间" class="font-black">
              <el-date-picker v-model="date"
                              :disabled="loading"
                              :shortcuts="shortcuts"
                              :size="store.layoutSize"
                              clearable
                              end-placeholder="结束日期"
                              range-separator="-"
                              start-placeholder="开始日期"
                              style="width: 210px"
                              type="daterange"
                              unlink-panels
                              value-format="YYYY-MM-DD"
                              @change="getUserData"
              />
            </el-form-item>
            <el-form-item>
              <el-button :color="store.getTheme" :disabled="loading" :size="store.layoutSize" auto-insert-space
                         @click="getUserData">
                <template #icon>
                  <el-icon>
                    <Search/>
                  </el-icon>
                </template>
                查询
              </el-button>
              <el-button :color="store.getTheme" :disabled="loading" :size="store.layoutSize" auto-insert-space plain
                         @click="clearSearch">
                <template #icon>
                  <el-icon>
                    <Refresh/>
                  </el-icon>
                </template>
                重置
              </el-button>
            </el-form-item>
          </el-form>
        </el-col>

        <el-col class="flex justify-between">
          <div>
            <el-button :color="store.getTheme" :disabled="loading" :size="store.layoutSize" auto-insert-space plain
                       type="primary"
                       @click="add">
              <template #icon>
                <el-icon>
                  <Plus/>
                </el-icon>
              </template>
              新增
            </el-button>
            <el-button :disabled="delDisabled || loading" :size="store.layoutSize" auto-insert-space plain type="danger"
                       @click="delSelect">
              <template #icon>
                <el-icon>
                  <Delete/>
                </el-icon>
              </template>
              删除
            </el-button>
            <el-button :disabled="loading" :size="store.layoutSize" auto-insert-space plain type="info">
              <template #icon>
                <el-icon>
                  <Upload/>
                </el-icon>
              </template>
              导入
            </el-button>
            <el-button :disabled="search.total === 0 || loading" :size="store.layoutSize" auto-insert-space plain
                       type="warning"
                       @click="download">
              <template #icon>
                <el-icon>
                  <Download/>
                </el-icon>
              </template>
              导出
            </el-button>
          </div>
          <div>
            <el-tooltip
                class="box-item"
                effect="dark"
                :content="showSearch?'隐藏搜索':'显示搜索'"
                placement="top"
            >
              <el-button :color="store.getTheme" :size="store.layoutSize" @click="showSearch = !showSearch" circle>
                <el-icon>
                  <Search/>
                </el-icon>
              </el-button>
            </el-tooltip>
            <el-tooltip
                class="box-item"
                effect="dark"
                content="刷新"
                placement="top"
            >
              <el-button :color="store.getTheme" :disabled="loading" :size="store.layoutSize" circle
                         @click="getUserData">
                <el-icon>
                  <Refresh/>
                </el-icon>
              </el-button>
            </el-tooltip>
          </div>
        </el-col>

        <el-col class="mt-2">
          <el-table :size="store.layoutSize" v-loading="loading" element-loading-text="正在努力加载中..."
                    :data="userTableData.data"
                    style="width: 100%" table-layout="auto" row-key="id" @selection-change="handleSelectionChange"
                    highlight-current-row empty-text="无数据">

            <el-table-column align="center" reserve-selection="true" type="selection" :color="store.getTheme"
                             width="55"/>

            <el-table-column align="center" label="用户编号" width="80" prop="userId"/>

            <el-table-column align="center" label="用户名称" prop="userName"/>

            <el-table-column align="center" label="用户昵称" prop="nickName"/>

            <el-table-column align="center" label="部门" prop="sysDept.deptName"/>

            <el-table-column align="center" label="手机号码" prop="phonenumber"/>

            <el-table-column align="center" label="状态">
              <template #default="scope">
                <el-switch v-if="scope.row.userId !== store.getUser.userId" @change="changeStatus(scope.row,$event)"
                           :active-color="store.getTheme"
                           v-model="scope.row.status" active-value="0"
                           inactive-value="1"/>
              </template>
            </el-table-column>

            <el-table-column align="center" label="创建时间" width="180">
              <template #default="scope">
                {{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
              </template>
            </el-table-column>

            <el-table-column align="center" label="操作">
              <template #default="scope">
                <template v-if="scope.row.userId !== store.getUser.userId">
                  <el-link :underline="false" class="text-xs" :style="{color: store.getTheme}"
                           @click="update(scope.row)">
                    <el-icon>
                      <EditPen/>
                    </el-icon>
                    修改
                  </el-link>
                  <el-link :underline="false" class="text-xs ml-3" :style="{color: store.getTheme}"
                           v-if="scope.row.parentId !== 0" @click="del(scope.row)">
                    <el-icon>
                      <Delete/>
                    </el-icon>
                    删除
                  </el-link>
                  <el-link :underline="false" class="text-xs ml-3" :style="{color: store.getTheme}">
                    <el-icon>
                      <DArrowRight/>
                    </el-icon>
                    更多
                  </el-link>
                </template>
              </template>
            </el-table-column>
          </el-table>
        </el-col>
        <el-col class="mt-3 flex justify-end">
          <el-pagination
              :small="store.layoutSize === 'small'"
              :default-current-page="search.pageNum"
              :currentPage="search.pageNum"
              :page-size='search.pageSize'
              :page-sizes="[10, 20, 50, 100]"
              :pager-count="5"
              layout="total, sizes, prev, pager, next, jumper"
              :total="search.total"
              @size-change="handlePageSizeChange"
              @current-change="handleCurrentPageChange"
          />
        </el-col>
      </el-row>
    </el-col>

    <!-- 添加或修改用户配置对话框 -->
    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户昵称" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="归属部门" prop="deptId">
              <el-tree-select
                  v-model="form.deptId"
                  :data="tableData.data"
                  node-key="deptId"
                  :props="{label:'deptName'}"
                  highlight-current
                  check-strictly
                  :show-count="true"
                  :render-after-expand="false" placeholder="请选择归属部门"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="手机号码" prop="phonenumber">
              <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
              <el-input ref="userNameInput" @input="form.password = null" v-model="form.userName"
                        placeholder="请输入用户名称"
                        maxlength="30"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
              <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20"
                        show-password/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户性别">
              <el-select v-model="form.sex" placeholder="请选择性别">
                <el-option
                    v-for="item in sexData.data"
                    :key="item.dictCode"
                    :label="item.dictLabel"
                    :value="item.dictValue"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="form.status" :fill="store.getTheme" :text-color="store.getTheme">
                <el-radio v-for="item in statusData.data"
                          :key="item.dictCode"
                          :label="item.dictValue">{{
                    item.dictLabel
                  }}
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col>
            <el-form-item label="角色">
              <el-select style="width: 100%" v-model="form.roleIds" multiple placeholder="请选择角色">
                <el-option
                    v-for="item in roleData.data"
                    :key="item.roleId"
                    :label="item.roleName"
                    :value="item.roleId"
                    :disabled="item.status === 1"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="flex justify-end">
        <el-button :color="store.getTheme" :loading="btnLoading" auto-insert-space @click="submitForm(formRef)">确定
        </el-button>
        <el-button auto-insert-space @click="open = false">取消</el-button>
      </div>
    </el-dialog>
  </el-row>
</template>

<script setup lang="ts">
import {nextTick, reactive, ref} from "vue";
import {useStore} from "@/store";
import {getDeptData} from "@/api/dept";
import moment from "moment";
import {getDictData} from "@/api/dictData";
import {delUser, downloadUser, saveUser, saveUserInfo, selectUserData} from "@/api/user";
import {ElMessageBox, ElNotification, FormInstance, FormRules} from "element-plus";
import {getAllRole, getRolesByUserId} from "@/api/role";
//引入store
const store = useStore()

//表格加载
const loading = ref(false)

//禁用删除按钮
const delDisabled = ref(true)

//是否显示搜索框
const showSearch = ref(true)

//部门搜索输入
const deptSearch = ref('')
const treeRef = ref(null)

function searchDept() {
  treeRef.value.filter(deptSearch.value.trim())
}

//筛选部门节点
function filterNode(val, data) {
  if (!val) return true
  return data.deptName.indexOf(val) !== -1
}

//是否显示弹出层
const open = ref(false)

//弹出层标题
const title = ref('')

const formRef = ref<FormInstance>()

//赋值部门数据
const tableData = reactive({
  data: []
})
getDeptData({'deptName': deptSearch.value}).then(result => {
  tableData.data = result.data.data
})

//赋值状态信息
const statusData = reactive({
  data: []
})
getDictData({'dictType': 'sys_normal_disable'}).then(result => {
  statusData.data = result.data.data
})

//赋值状态信息
const sexData = reactive({
  data: []
})
getDictData({'dictType': 'sys_user_sex'}).then(result => {
  sexData.data = result.data.data
})

//赋值角色列表
const roleData = reactive({
  data: []
})
getAllRole().then(result => {
  roleData.data = result.data.data
})

//创建时间区间时间
const date = ref([])

//定义选中的行
const multipleSelection = ref<[]>([])
const handleSelectionChange = (val: []) => {
  const arr = []
  val.filter(item => {
    arr.push(item.userId)
  })
  multipleSelection.value = arr
  if (multipleSelection.value.length > 0) {
    delDisabled.value = false
  } else {
    delDisabled.value = true
  }
}

//单独删除
function del(val) {
  ElMessageBox.confirm('您确定要删除<' + val.userName + '>用户吗？', '警告', {
    confirmButtonText: '删除',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    delUser({userId: val.userId}).then(result => {
      if (result.data.code === 200) {
        ElNotification({
          message: result.data.msg,
          type: 'success'
        })
      }
      getUserData()
    })
  })
}

//批量删除
function delSelect() {
  ElMessageBox.confirm('您确定要删除编号为[' + multipleSelection.value + ']的用户吗？', '警告', {
    confirmButtonText: '删除',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    delUser({userIds: multipleSelection.value}).then(result => {
      if (result.data.code === 200) {
        ElNotification({
          message: result.data.msg,
          type: 'success'
        })
      }
      getUserData()
    })
  })
}

//查询表单
const search = reactive({
  deptId: null,
  userName: null,
  phonenumber: null,
  status: null,
  startDate: null,
  endDate: null,
  pageNum: 1,
  pageSize: 10,
  total: 0,
})

//清空查询表单
function clearSearch() {
  search.userName = null
  search.phonenumber = null
  search.status = null
  search.startDate = null
  search.endDate = null
  date.value = []
  getUserData()
}

//赋值用户表格数据
const userTableData = reactive({
  data: []
})
getUserData()

function getUserData() {
  loading.value = true
  if (date.value && date.value.length > 0) {
    search.startDate = date.value[0]
    search.endDate = date.value[1]
  } else {
    search.startDate = null
    search.endDate = null
  }
  selectUserData(search).then(result => {
    userTableData.data = result.data.data.list
    search.total = result.data.data.total
    loading.value = false
  })
}

//部门点击事件
function deptClick(val) {
  search.deptId = val.deptId
  getUserData()
}

//分页方法
function handleCurrentPageChange(val) {
  search.pageNum = val
  getUserData()
}

//页大小切换
function handlePageSizeChange(val) {
  search.pageSize = val
  getUserData()
}

//时间选择器快捷选择
const shortcuts = [
  {
    text: '上周内',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
  },
  {
    text: '近一个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    },
  },
  {
    text: '近三个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    },
  },
]

//新增、修改表单数据
const form = reactive({
  userId: null,
  deptId: null,
  userName: null,
  nickName: null,
  password: null,
  phonenumber: null,
  email: null,
  sex: null,
  status: "0",
  remark: null,
  roleIds: [],
  createBy: null,
  updateBy: null,
})

//清空表单
function clearForm() {
  form.userId = null
  form.deptId = null
  form.userName = null
  form.nickName = null
  form.password = null
  form.phonenumber = null
  form.email = null
  form.sex = null
  form.status = "0"
  form.remark = null
  form.roleIds = []
  form.createBy = null
  form.updateBy = null
}

//新增方法
function add() {
  clearForm()
  title.value = '添加用户'
  form.createBy = store.getUser.userName
  open.value = true
}

//更新方法
function update(val) {
  clearForm()
  form.userId = val.userId
  form.deptId = val.deptId
  //form.userName = val.userName
  form.nickName = val.nickName
  //form.password = val.password
  form.phonenumber = val.phonenumber
  form.email = val.email
  form.sex = val.sex
  form.status = val.status
  form.remark = val.remark
  form.updateBy = store.getUser.userName
  title.value = '修改用户'
  getRolesByUserId({userId: val.userId}).then(result => {
    console.log(result.data)
    form.roleIds = result.data.data
    open.value = true
  })
}

//表格中状态切换开关
function changeStatus(row, val) {
  ElMessageBox.confirm('确定要' + (val === '0' ? '启用' : '停用') + '<' + row.userName + '>用户吗？', '系统提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {

    saveUserInfo({userId: row.userId, status: val}).then(result => {
      if (result.data.code === 200) {
        ElNotification({
          type: 'success',
          title: val === '0' ? '启用成功' : '停用成功',
        })
      } else {
        ElNotification({
          type: 'error',
          title: val === '0' ? '启用失败，稍后再试' : '停用失败，稍后再试',
        })
        getUserData()
      }
    })

  }).catch(() => {
    if (val === '0') {
      row.status = '1';
    } else {
      row.status = '0';
    }

  })
}

//用户名输入框
const userNameInput = ref()

const btnLoading = ref(false)

//提交表单
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid) => {
    if (valid) {
      btnLoading.value = true
      saveUser(form).then(result => {
        if (result.data.code !== 200) {
          form.userName = null
          form.password = null
          nextTick(() => {
            userNameInput.value.focus()
          })
        } else {
          ElNotification({
            message: result.data.msg,
            type: 'success'
          })
          open.value = false
          getUserData()
        }
        btnLoading.value = false
      })
    }
  })
}

// 表单校验
const rules = reactive<FormRules>({
  userName: [
    {required: true, message: "用户名称不能为空", trigger: "blur"},
    {min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur'}
  ],
  nickName: [
    {required: true, message: "用户昵称不能为空", trigger: "blur"}
  ],
  password: [
    {required: true, message: "用户密码不能为空", trigger: "blur"},
    {min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur'}
  ],
  email: [
    {
      type: "email",
      message: "请输入正确的邮箱地址",
      trigger: ["blur", "change"]
    }
  ],
  phonenumber: [
    {
      pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
      message: "请输入正确的手机号码",
      trigger: "blur"
    }
  ]
})

//导出数据
function download() {
  ElMessageBox.confirm('您确定要导出<' + search.total + '>条数据吗？', '警告', {
    confirmButtonText: '导出',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    downloadUser(search).then(response => {
      let disposition = response.headers['content-disposition'];
      //以下部分有需要优化，如后端返回时没有携带文件后缀名,没有.时会有问题等等
      let filename = disposition ? disposition.substring(disposition.indexOf('=') + 1, disposition.indexOf('.')) : "下载文件";
      let newName = decodeURI(escape(filename))
      let extName = disposition.substring(disposition.indexOf('.') + 1)
      let blob = new Blob([response.data], {type: 'application/vnd.ms-excel'});
      let link = document.createElement("a");
      let evt = document.createEvent("HTMLEvents");
      evt.initEvent("click", false, false);
      link.href = URL.createObjectURL(blob);
      link.download = newName + "." + extName;
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      window.URL.revokeObjectURL(link.href);
    })
  })
}
</script>

<style scoped>

</style>
